from myhdl import *
from random import randrange


# software reg which can be written or read from the ppc
def software_reg(OPB_clk,
                 OPB_rst,
                 Sl_xferAck,
                 Sl_DBus,
                 Sl_toutSup,
                 Sl_retry,
                 Sl_errAck,
                 OPB_DBus,
                 OPB_ABus,
                 OPB_RNW,
                 OPB_select,
                 user_clk,
                 user_data_out,
                 C_BASEADDR = hex(0x00000000),
                 C_HIGHADDR = hex(0x0000FFFF),
                 C_OPB_AWIDTH = 0,
                 C_OPB_DWIDTH = 0,
                 C_FAMILY = "default"):

   Sl_DBus_reg, reg_buffer, user_data_out_reg = [Signal(intbv(0)[32:]) for i in range (3)]
   Sl_xferAck_reg, register_done, register_doneR, register_doneRR, register_OPB_DBus, register_ready, register_readyR, register_readyRR = [Signal(bool(0)) for i in range(8)]
   
   @always_comb
   def assigns():
      Sl_DBus.next = Sl_DBus_reg
      Sl_toutSup.next = 0
      Sl_retry.next = 0
      Sl_errAck.next = 0
      Sl_xferAck.next = Sl_xferAck_reg
      user_data_out.next = user_data_out_reg

   # combantorial logic
   @always_comb
   def comb_logic():
      #a_match.next = OPB_ABus >= C_BASEADDR
      #if((OPB_ABus >= C_BASEADDR) and (OPB_ABus <= C_HIGHADDR)):
      #   a_match = True
      #else:
      #   a_match = False
      if(Sl_xferAck_reg == 0):
         Sl_DBus_reg.next = Signal(intbv(0)[4:])
      else:
         Sl_DBus_reg.next = reg_buffer

   # OPB_clk logic
   @always(OPB_clk.posedge)
   def OPB_clk_logic():
      Sl_xferAck_reg.next = 0 
      register_doneR.next = register_done
      register_doneRR.next = register_doneR
      if (OPB_rst):
         register_ready.next = 0
      else:
	 if (OPB_select and not Sl_xferAck_reg):
            Sl_xferAck_reg.next = 1
            if (not OPB_RNW):
               reg_buffer.next[31:0] = OPB_DBus[0:31]
               register_ready.next = 1
         if (register_doneRR):
            register_ready.next = 0

      

   # system clock Logic
   @always(user_clk.posedge)
   def user_clk_logic():
      register_readyR.next = register_ready
      register_readyRR.next = register_readyR

      if not register_readyRR:
         register_done.next = 0
      else:
         register_done.next = 1
         user_data_out_reg.next = reg_buffer


   return comb_logic, assigns, OPB_clk_logic, user_clk_logic



def convert():

    OPB_clk, OPB_rst, Sl_xferAck, Sl_toutSup, Sl_retry, Sl_errAck, OPB_RNW, OPB_select, user_clk = [Signal(bool(0)) for i in range(9)]
    Sl_DBus, OPB_ABus, OPB_DBus, user_data_out = [Signal(intbv(0)[32:]) for i in range(4)]
    OPB_BE = [Signal(intbv(0)[3:])for i in range(1)]

    toVerilog(software_reg,
              OPB_clk,
              OPB_rst,
              Sl_xferAck,
              Sl_DBus,
              Sl_toutSup,
              Sl_retry,
              Sl_errAck,
              OPB_DBus,
              OPB_ABus,
              OPB_RNW,
              OPB_select,
              user_clk,
              user_data_out,
              "",
              "",
              "")

#convert()
